package com.xxxx.springsecuritydemo.config;

import com.xxxx.springsecuritydemo.handle.MyAccessDeniedHandler;
import com.xxxx.springsecuritydemo.handle.MyAuthenticationSuccessHandler;
import com.xxxx.springsecuritydemo.service.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

/***
 * SpringSecurity配置类
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//    @Autowired
//    private MyAccessDeniedHandler myAccessDeniedHandler;
    @Autowired
    private UserDetailsServiceImpl userService;
    @Autowired
    private PersistentTokenRepository persistentTokenRepository;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 表单提交
        http.formLogin()
                // 自定义用户名和密码的请求参数
                .usernameParameter("username")
                .passwordParameter("password")
                // 当发现/login请求时认为是登陆, 必须和表单提交的地址一样, 去执行
                .loginProcessingUrl("/login")
                // 自定义登陆页面
                .loginPage("/showLogin")

                // 自定义失败时候需要跳转的地址, 需要是post
                .failureForwardUrl("/toError")
                // 自定义跳转站外
//                .failureHandler(new MyAuthenticationFailureHandler("/error.html"))
                // 自定义登陆成功的需要跳转的地址, 需要post,
                .successForwardUrl("/toMain");
                // 自定义跳转站外(重定向)
//                .successHandler(new MyAuthenticationSuccessHandler("/main.html"));
        // 授权认证
        http.authorizeRequests()
                .antMatchers("/error.html").permitAll()
                // login页面直接放行(直接认证)
//                .antMatchers("/login.html").permitAll()
                .antMatchers("/showLogin").access("permitAll")
                // 静态资源放行
                .antMatchers("/js/**","/css/**","/images/**").permitAll()
                //.antMatchers("/**/*.png").permitAll()
                // 正则匹配
                //.regexMatchers(".+[.]jpg").permitAll()
                // 请求方法匹配
                //.antMatchers(HttpMethod.GET, "/demo").permitAll()
                //  servletPath匹配
//                .mvcMatchers("/demo").servletPath("/xxxx").permitAll()
                //.antMatchers("/xxxx/demo").permitAll()
                // 权限判断
                .antMatchers("/admin.html").hasAuthority("admin")
                // 角色判断
//                .antMatchers("/admin.html").hasRole("abc")
//                .antMatchers("/admin.html").hasIpAddress("192.168.0.2")
                // 所有的请求都必须要认证后才能被访问
                .anyRequest().authenticated();
                // 自定义判断当前登陆的用户是否有访问当前url的权限
//                .anyRequest().access("@myServiceImpl.hasPermission(request, authentication)");
        // 禁用csrf(现在可以认为是防火墙)
//        http.csrf().disable();

        // 异常处理
        http.exceptionHandling()
                .accessDeniedHandler(new MyAccessDeniedHandler());
        http.rememberMe()
                //失效时间，单位秒
                .tokenValiditySeconds(120)
                //登录逻辑交给哪个对象
                .userDetailsService(userService)
                // 持久层对象
                .tokenRepository(persistentTokenRepository);
        http.logout()
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login.html");
    }


}
